package com.nannybear.Model;

import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;

import com.jjoe64.graphview.series.DataPoint;
import com.nannybear.MainActivity;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * \brief Save and retrieves information which need to be saved
 * \author Audrey LOISEAU
 * \date 7-05-2015
 */

/********************************* COPYRIGHT *********************************
 * Copyright (c) 2015, Audrey LOISEAU and Benjamin LANCINOT.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *************************************************************************************/

public class Yoda{
    /********** DECLARATIONS **********/
    private MainActivity mActivity;

    /************ METHODS ************/
    /**
     * \brief Constructor
     * \param activity  The activity
     */
    public Yoda(MainActivity activity){
        this.mActivity = activity;
    }

    /**
     * \brief Retrieves the shared preferences (string)
     * \param key   The key to find the information
     * \param defaultValue  The default value if nothing has been changed
     */
    public String retrievesSharedPreferencesString(String key, String defaultValue){
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mActivity.getApplicationContext());
        String value = sharedPreferences.getString(key, "");
        if(value.equals("")){
            value = defaultValue;
        }
        return value;
    }

    /**
     * \brief Retrieves the shared preferences (double)
     * \param key   The key to find the information
     * \param defaultValue  The default value if nothing has been changed
     */
    public double retrievesSharedPreferencesLong(String key, int defaultValue){
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mActivity.getApplicationContext());
        Long value = sharedPreferences.getLong(key, 0);
        if(value == 0){
            value = (long)defaultValue;
        }
        return (Double.valueOf(value));
    }

    /**
     * \brief Saves the preferences (string)
     * \param key   The key to save the value
     * \param value The value to save
     */
    public void savedPreferences(String key, String value){
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mActivity.getApplicationContext());
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, value);
        editor.apply();
    }

    /**
     * \brief Saves the preferences (long)
     * \param key   The key to retrieves the value
     * \param value The value to find
     */
    public void savedPreferencesLong(String key, Long value){
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mActivity.getApplicationContext());
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putLong(key, value);
        editor.apply();
    }

    /**
     * \brief Save information in array list with JSon
     * \param array The list to save
     * \param key   The key to save the information
     */
    public void savetoJSON(ArrayList<DataPoint> array, String key){
        JSONArray jsonArray = new JSONArray();
        try{
            for(int i=0;i<array.size();i++){
                JSONObject jsOb = new JSONObject();
                jsOb.put("age",array.get(i).getX());
                jsOb.put(key,array.get(i).getY());
                jsonArray.put(jsOb);
            }
        }catch(JSONException e){
            Log.e("log_tag", "Error parsing data "+e.toString());
        }
        this.savedPreferences(key,jsonArray.toString());
    }

    /**
     * \brief Save event in array list with JSon
     * \param key   The key to save the information
     * \param eventMap The event map to save
     */
    public void saveEventsToJSON(String key, HashMap<String, Event[]> eventMap){
        JSONObject jsonObject = new JSONObject();
        Iterator i = eventMap.entrySet().iterator();
        try{
            while(i.hasNext()){
                Map.Entry mEntry =(Map.Entry) i.next();
                String mKey = (String)mEntry.getKey();
                JSONArray jsonArray = new JSONArray();

                for(int j=0; j<eventMap.get(mKey).length; j++){
                    JSONObject event = new JSONObject();
                    event.put("icon",eventMap.get(mKey)[j].icon);
                    event.put("time",eventMap.get(mKey)[j].time);
                    event.put("event",eventMap.get(mKey)[j].event);
                    jsonArray.put(event);
                 }
                 jsonObject.put(mKey,jsonArray);
            }
        }catch(JSONException ex){
            Log.e("Yoda","Pb to save data : "+ex.getMessage());
        }
        this.savedPreferences(key, jsonObject.toString());
    }

    /**
     * \brief Retrieves the shared preferences (event)
     * \param key   The key to find the information
     */
    public void retrieveEventFromJSON(String key) {
        String events = retrievesSharedPreferencesString(key, "");
        try {
            if (!events.equals("")) {
                JSONObject jsonObject = new JSONObject(events);
                Iterator iterator = jsonObject.keys();
                while(iterator.hasNext()){
                    String mKey = (String)iterator.next();
                    JSONArray jsonArray = jsonObject.getJSONArray(mKey);
                     for(int i=0 ; i<jsonArray.length() ; i++){
                         String icon = jsonArray.getJSONObject(i).get("icon").toString();
                         String event = jsonArray.getJSONObject(i).get("event").toString();
                         String time = jsonArray.getJSONObject(i).get("time").toString();
                         mActivity.getViewPuppeteer().getCalendarController().getEventsCalendar().addEvent(mKey, icon, event, time);
                     }
                }
            }
        } catch (JSONException ex) {
            Log.e("Yoda", "Pb to retrieve : " + ex.getMessage());
        }
    }

    /**
     * \brief Retrieves the shared preferences (graph)
     * \param key   The key to find the information
     */
    public ArrayList<DataPoint> retrievefromJSON(String key){

        ArrayList<DataPoint> arrayList = new ArrayList<DataPoint>();
        String jSONString = retrievesSharedPreferencesString(key, "");

        try{
            if(jSONString != "") {
                JSONArray jsonArray = new JSONArray(jSONString);

                for (int i = 0; i < jsonArray.length(); i++) {
                    double age = Double.parseDouble(jsonArray.getJSONObject(i).get("age").toString());
                    double data = Double.parseDouble(jsonArray.getJSONObject(i).get(key).toString());
                    arrayList.add(new DataPoint(age, data));
                }
            }
        }catch(JSONException e){
            Log.e("log_tag", "Error parsing data "+e.toString());
        }
        return arrayList;
    }
}
